package multithreading;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * @Author: 海琳琦
 * @Date: 2022/4/3 22:36
 * 线程创建方式三：创建Callable接口（与Runnable相比，Callable功能更加强大）
 *                1、call()方法相比于run()方法，可以有返回值
 *                2、call()方法可以抛出异常
 *                3、call()支持泛型的返回值
 *                4、需要借助FutureTask类启动(Future可以对具体的Runnable、Callable任务的执行结果进行取消、查询是否完成、获取结果等。）
 *                                            FutureTask是Future接口的唯一实现类。它实现了Runnable、Callable接口。
 *                                            既可以作为Runnable被线程执行，又可以作为Future得到Callable的返回值。
 * 步骤1、创建一个实现Callable接口的实现类
 *     2、实现Call()方法，将线程执行的操作声明在该方法中
 *     3、创建Callable接口实现类的对象
 *     4、将Callable接口实现类的对象作为参数传递给FutureTask的构造器中，创建FutureTask的对象
 *     5、将FutureTask对象作为参数传递给Thread的构造器中，创建Thread对象，并调用start()方法
 *     6、[可选]获取callable中call方法中的返回值futureTask.get()
 */
class MyThread2 implements Callable<Integer>{

    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i < 100; i++) {
            if (i % 2 == 0) {
                sum += i;
            }
        }
        return sum;
    }

}

public class ThreadCreate2 {
    public static void main(String[] args) {
        MyThread2 myThread3 = new MyThread2();
        FutureTask<Integer> futureTask = new FutureTask<>(myThread3);
        new Thread(futureTask).start();
        try {
            //get方法的返回值即为FutureTask构造器形参Callable实现类重写call方法的返回值
            Integer sum = futureTask.get();
            System.out.println(sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
